package com.caocaog.market.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caocaog.market.data.transfer.service.MkSiteBasicService;
import com.caocaog.market.entity.ShopChannel;
import com.caocaog.market.entity.dto.ShopChannelTreeDTO;
import com.caocaog.market.mapper.ShopChannelMapper;
import com.caocaog.market.merchant.entity.MkMerchantBasic;
import com.caocaog.market.merchant.service.MkMerchantService;
import com.caocaog.market.service.IShopBasicService;
import com.caocaog.market.service.IShopChannelService;
import com.caocaog.market.util.CollectionsUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 频道信息表
 * @Author: jeecg-boot
 * @Date: 2021-11-19
 * @Version: V1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ShopChannelServiceImpl extends ServiceImpl<ShopChannelMapper, ShopChannel> implements IShopChannelService {

    private final MkSiteBasicService mkSiteBasicService;
    private final MkMerchantService mkMerchantService;

    @Override
    public void addShopChannel(ShopChannel shopChannel) {
        //新增时设置hasChild为0
        shopChannel.setHasChild(NOCHILD);
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        // 若为商家角色，那么商家添加的就是自己特有的频道信息
        if (loginUser.getUserType() == 3) {
            MkMerchantBasic merchantBasic = mkMerchantService.findByUserId(loginUser.getId());
            shopChannel.setSiteId(merchantBasic.getId());
        }
        shopChannel.setSiteId(loginUser.getSiteId());
        if (oConvertUtils.isEmpty(shopChannel.getParentId())) {
            shopChannel.setParentId(ROOT_PID_VALUE);
        } else {
            //如果当前节点父ID不为空 则设置父节点的hasChildren 为1
            ShopChannel parent = baseMapper.selectById(shopChannel.getParentId());
            if (parent != null && !"1".equals(parent.getHasChild())) {
                parent.setHasChild("1");
                baseMapper.updateById(parent);
            }
        }
        baseMapper.insert(shopChannel);
    }

    @Override
    public void updateShopChannel(ShopChannel shopChannel) {
        ShopChannel entity = this.getById(shopChannel.getId());
        if (entity == null) {
            throw new JeecgBootException("未找到对应实体");
        }
        String old_pid = entity.getParentId();
        String new_pid = shopChannel.getParentId();
        if (!old_pid.equals(new_pid)) {
            updateOldParentNode(old_pid);
            if (oConvertUtils.isEmpty(new_pid)) {
                shopChannel.setParentId(ROOT_PID_VALUE);
            }
            if (!ROOT_PID_VALUE.equals(shopChannel.getParentId())) {
                baseMapper.updateTreeNodeStatus(shopChannel.getParentId(), HASCHILD);
            }
        }
        baseMapper.updateById(shopChannel);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteShopChannel(String id) throws JeecgBootException {
        //查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if (id.indexOf(",") > 0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if (idVal != null) {
                    ShopChannel shopChannel = this.getById(idVal);
                    String pidVal = shopChannel.getParentId();
                    //查询此节点上一级是否还有其他子节点
                    List<ShopChannel> dataList = baseMapper.selectList(new QueryWrapper<ShopChannel>().eq("parent_id", pidVal).notIn("id", Arrays.asList(idArr)));
                    if ((dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(pidVal)
                            && !sb.toString().contains(pidVal)) {
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for (String pid : pidArr) {
                this.updateOldParentNode(pid);
            }
        } else {
            ShopChannel shopChannel = this.getById(id);
            if (shopChannel == null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(shopChannel.getParentId());
            baseMapper.deleteById(id);
        }
    }

    @Override
    public List<ShopChannel> queryTreeListNoPage(QueryWrapper<ShopChannel> queryWrapper) {
        List<ShopChannel> dataList = baseMapper.selectList(queryWrapper);
//        List<ShopChannel> mapList = new ArrayList<>();
        // todo 意义不明的代码？
//        for (ShopChannel data : dataList) {
//            String pidVal = data.getParentId();
//            //递归查询子节点的根节点
//            if (pidVal != null && !"0".equals(pidVal)) {
//                ShopChannel rootVal = this.getTreeRoot(pidVal);
//                if (rootVal != null && !mapList.contains(rootVal)) {
//                    mapList.add(rootVal);
//                }
//            } else {
//                if (!mapList.contains(data)) {
//                    mapList.add(data);
//                }
//            }
//        }
        return dataList;
    }

    @Override
    public List<ShopChannel> queryTreeListByPid(String pid) {
        List<ShopChannel> shopChannels = baseMapper.selectList(new QueryWrapper<ShopChannel>()
                .eq("parent_id", pid));
        return shopChannels;
    }


    @Override
    public int setTop(String id) {
        // 设置顶置前先查询已经顶置了多少个，超过顶置最大数就不能顶置了
        int topCount = super.baseMapper.selectCount(new LambdaQueryWrapper<ShopChannel>()
                .eq(ShopChannel::getIsTop, 1));
        if (CommonConstant.TOP_COUNT_MAX == topCount || CommonConstant.TOP_COUNT_MAX < topCount) {
            throw new JeecgBootException("已经要超出设定的顶置数量，不能再顶置了");
        }
        return super.baseMapper.update(null, new LambdaUpdateWrapper<ShopChannel>()
                .set(ShopChannel::getIsTop, 1)
                // 根节点，无上级id
                .eq(ShopChannel::getParentId, 0)
                // 需为系统频道
                .eq(ShopChannel::getSiteId, 0)
                .eq(ShopChannel::getId, id)
        );
    }

    @Override
    public int setBottom(String id) {
        return super.baseMapper.update(null, new LambdaUpdateWrapper<ShopChannel>()
                .set(ShopChannel::getIsTop, 0)
                // 根节点，无上级id
                .eq(ShopChannel::getParentId, 0)
                // 需为系统频道
                .eq(ShopChannel::getSiteId, 0)
                .eq(ShopChannel::getId, id)
        );
    }

    @Override
    public List<ShopChannel> getSecondaryLevelChannel(String channelId, String siteId) {
        return super.baseMapper.selectList(new LambdaQueryWrapper<ShopChannel>()
                .eq(ShopChannel::getParentId, channelId)
                .and(StringUtils.isNotBlank(siteId),
                        i -> i.eq(ShopChannel::getSiteId, siteId).or().eq(ShopChannel::getSiteId, "0"))
        );
    }

    /**
     * 构建二级频道List
     *
     * @return 查询结果
     */
    @Override
    public Set<ShopChannelTreeDTO> childChoseList() {
        List<ShopChannel> shopChannelList = list();
        // 筛选出父节点与子节点
        Set<ShopChannel> fathers = shopChannelList.stream().filter(sourceChannel -> "0".equals(sourceChannel.getParentId())).collect(Collectors.toSet());
        Set<ShopChannel> children = shopChannelList.stream().filter(e -> !fathers.contains(e)).collect(Collectors.toSet());
        // 构建子节点为前端需要的格式List,然后在根据Pid进行分组成Map
        Map<String, List<ShopChannelTreeDTO>> channelMapGroupByPid = children.stream()
                .map(sourceChannel -> new ShopChannelTreeDTO().setKey(sourceChannel.getId()).setTitle(sourceChannel.getName()).setValue(sourceChannel.getId()).setPid(sourceChannel.getParentId()))
                .collect(Collectors.groupingBy(ShopChannelTreeDTO::getPid));
        // 构建返回的DTOSet
        Set<ShopChannelTreeDTO> channelTreeSet = fathers.stream()
                .map(sourceChannel -> new ShopChannelTreeDTO().setKey(sourceChannel.getId()).setTitle(sourceChannel.getName()).setValue(sourceChannel.getId()).setPid("0"))
                .collect(Collectors.toSet());
        // 为父节点塞入子List
        channelTreeSet.forEach(treeNode -> {
            String fatherId = treeNode.getKey();
            List<ShopChannelTreeDTO> childList = channelMapGroupByPid.get(fatherId);
            treeNode.setChildren(childList);
        });
        return channelTreeSet;
    }

    @Override
    public List<ShopChannel> shopChannelHomeDisplayList(ShopChannel shopChannel) {

        /*
         * 该段代码，因为改造成曹操小店单代理商，单商户。所以不在需要根据经纬度取获取分站信息，而是直接定死郑州分站(1462979923839545346)
         */
//        // 校验
//        if (StringUtils.isNotBlank(shopChannel.getSiteId())) {
//            siteId = shopChannel.getSiteId();
//            // TODO 等小程序接口逐步替换成分站id参数后，就把经纬度判断等这些代码删掉
//        } else if (StringUtils.isNotBlank(shopChannel.getLat()) && StringUtils.isNotBlank(shopChannel.getLng())) {
//            siteId = this.mkSiteBasicService.getSurroundingSiteId(shopChannel.getLat(), shopChannel.getLng()).getSiteId();
//        } else {
//            throw new JeecgBootException(String.format("请传入分站id 或 经纬度 -> siteId: %s, lat: %s, lng: %s",
//                    shopChannel.getSiteId(), shopChannel.getLat(), shopChannel.getLng()));
//        }

        // 开始查询
        List<ShopChannel> systemList = this.getSystemList();
        Map<Integer, List<ShopChannel>> topAndLastMap = systemList.stream().collect(Collectors.groupingBy(ShopChannel::getIsTop, Collectors.toList()));
        List<ShopChannel> systemTop = topAndLastMap.get(1);
        List<ShopChannel> systemLast = topAndLastMap.get(0);
        List<ShopChannel> siteChannel = super.baseMapper.selectList(new LambdaQueryWrapper<ShopChannel>()
                // 根节点，无上级id
                .eq(ShopChannel::getParentId, 0)
                // 要在首页展示
                .eq(ShopChannel::getIsIndex, 1)
                .eq(ShopChannel::getSiteId, shopChannel.getSiteId())
        );
        List<ShopChannel> mergeList = new ArrayList<>(7);
        if (!CollectionsUtil.isEmpty(systemTop))
            mergeList.addAll(systemTop);
        if (!CollectionsUtil.isEmpty(siteChannel))
            mergeList.addAll(siteChannel);
        if (!CollectionsUtil.isEmpty(systemLast))
            mergeList.addAll(systemLast);
        return mergeList;
    }

    /**
     * 获取系统频道信息
     *
     * @return 系统频道信息
     */
    private List<ShopChannel> getSystemList() {
        return super.baseMapper.selectList(new LambdaQueryWrapper<ShopChannel>()
                // 根节点，无上级id
                .eq(ShopChannel::getParentId, 0)
                // 系统频道
                .eq(ShopChannel::getSiteId, 0)
                // 要首页展示
                .eq(ShopChannel::getIsIndex, 1)
        );
    }


    /**
     * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
     *
     * @param pid
     */
    private void updateOldParentNode(String pid) {
        if (!ROOT_PID_VALUE.equals(pid)) {
            Integer count = baseMapper.selectCount(new QueryWrapper<ShopChannel>().eq("parent_id", pid));
            if (count == null || count <= 1) {
                baseMapper.updateTreeNodeStatus(pid, NOCHILD);
            }
        }
    }

    /**
     * 递归查询节点的根节点
     *
     * @param pidVal
     * @return
     */
    private ShopChannel getTreeRoot(String pidVal) {
        ShopChannel data = baseMapper.selectById(pidVal);
        if (data != null && !"0".equals(data.getParentId())) {
            return this.getTreeRoot(data.getParentId());
        } else {
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     *
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if (pidVal != null) {
                if (!sb.toString().contains(pidVal)) {
                    if (sb.toString().length() > 0) {
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal, sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 递归查询所有子节点
     *
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal, StringBuffer sb) {
        List<ShopChannel> dataList = baseMapper.selectList(new QueryWrapper<ShopChannel>().eq("parent_id", pidVal));
        if (dataList != null && dataList.size() > 0) {
            for (ShopChannel tree : dataList) {
                if (!sb.toString().contains(tree.getId())) {
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(), sb);
            }
        }
        return sb;
    }

}
